package com.un.ebs.sys.controller;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.un.ebs.core.enums.ScopeEnum;
import com.un.ebs.core.enums.UserTypeEnum;
import com.un.ebs.core.exception.BusinessException;
import com.un.ebs.core.util.SecurityUtils;
import com.un.ebs.core.util.WebResult;
import com.un.ebs.core.util.WebUtils;
import com.un.ebs.sys.domain.ConfigureExt;
import com.un.ebs.sys.domain.ConfigureValueExt;
import com.un.ebs.sys.dto.*;
import com.un.ebs.sys.mapper.ConfigureExtMapper;
import com.un.ebs.sys.mapper.ConfigureMapper;
import com.un.ebs.sys.mapper.ConfigureValueExtMapper;
import com.un.ebs.sys.mapper.ConfigureValueMapper;
import com.un.ebs.sys.service.ConfigureService;
import com.un.ebs.sys.service.ConfigureValueService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;


/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author liubo
 * @since 2019-11-01
 */
@RestController
@RequestMapping("/configure")
@Api(value = "sys-configure", description = "配置")
public class ConfigureController {

    @Autowired
    private ConfigureService service;

    @Autowired
    private ConfigureValueService configureValueService;

    @Autowired
    private ConfigureMapper configureMapper;

    @Autowired
    private ConfigureExtMapper configureExtMapper;

    @Autowired
    private ConfigureValueExtMapper configureValueExtMapper;

    @Autowired
    private ConfigureValueMapper configureValueMapper;

    @PostMapping("add")
    @ApiOperation(value = "add", notes = "添加")
    public WebResult save(@RequestBody @Validated ConfigureAddDto req) {
        service.add(req);
        return WebUtils.success();
    }

    @PostMapping("addValue")
    @ApiOperation(value = "addValue", notes = "添加配置值")
    public WebResult save(@RequestBody ConfigureValueAddDto req) {
        configureValueService.add(req);
        return WebUtils.success();
    }

    @PostMapping("update")
    @ApiOperation(value = "update", notes = "修改")
    public WebResult update(@RequestBody ConfigureUpdateDto req) {
        service.update(req);
        return WebUtils.success();
    }

    @PostMapping("updateValue")
    @ApiOperation(value = "updateValue", notes = "修改")
    public WebResult updateValue(@RequestBody ConfigureValueUpdateDto req) {
        configureValueService.update(req);
        return WebUtils.success();
    }

    @GetMapping("/{id}")
    @ApiOperation(value = "getById", notes = "根据主键获取单个 Configure")
    public WebResult getById(@PathVariable("id") String id) {
        return WebUtils.success(service.queryById(id));
    }


    @GetMapping("list/{id}")
    @ApiOperation(value = "listById", notes = "查询当前应用下的所有配置")
    public WebResult listById(@PathVariable("id") String id) {
        LambdaQueryWrapper<ConfigureExt> lq = Wrappers.lambdaQuery();
        lq.eq(ConfigureExt::getIsDelete, false);
        lq.eq(ConfigureExt::getAppId, id);
        lq.orderByAsc(ConfigureExt::getCode);
        List<ConfigureExt> configures = configureExtMapper.selectList(lq);

        List<ConfigureValueDto> result = new ArrayList<>();
        for (ConfigureExt configure : configures) {
            ConfigureValueDto configureValueDto = new ConfigureValueDto();
            configureValueDto.setId(configure.getId());
            configureValueDto.setCode(configure.getCode());
            configureValueDto.setName(configure.getName());
            configureValueDto.setRemark(configure.getRemark());
            configureValueDto.setScope(configure.getScope());
            configureValueDto.setDefaultValue(configure.getDefaultValue());
            configureValueDto.setGroupId(configure.getGroupId());
            configureValueDto.setGroupName(configure.getGroupName());
            result.add(configureValueDto);
        }
        return WebUtils.success(result);
    }

    @GetMapping("list")
    @ApiOperation(value = "list", notes = "查询当前应用下的所有配置")
    public WebResult list() {
        if (!(SecurityUtils.getUserContent().getType() == UserTypeEnum.TENANT_ADMIN || SecurityUtils.getUserContent().getType() == UserTypeEnum.DEVELOPER)) {
            throw new BusinessException("你不是租户管理员角色，不能执行此操作。");
        }

        LambdaQueryWrapper<ConfigureExt> lq = Wrappers.lambdaQuery();
        lq.eq(ConfigureExt::getIsDelete, false);
        lq.eq(ConfigureExt::getAppId, SecurityUtils.getUserContent().getAppId());
        lq.orderByAsc(ConfigureExt::getCode);
        List<ConfigureExt> configures = configureExtMapper.selectList(lq);

        LambdaQueryWrapper<ConfigureValueExt> lqValue = Wrappers.lambdaQuery();
        lqValue.or(obj -> obj.eq(ConfigureValueExt::getAppId, SecurityUtils.getUserContent().getAppId()).
                isNull(ConfigureValueExt::getTenantId).
                eq(ConfigureValueExt::getScope, ScopeEnum.Application));
        lqValue.or(obj -> obj.eq(ConfigureValueExt::getScope, ScopeEnum.Tenant).
                eq(ConfigureValueExt::getTenantId, SecurityUtils.getUserContent().getTenantId()));
        lqValue.orderByAsc(ConfigureValueExt::getCode);
        List<ConfigureValueExt> valueExts = configureValueExtMapper.selectList(lqValue);

        List<ConfigureValueDto> result = new ArrayList<>();
        Boolean isDev = SecurityUtils.getUserContent().getType() == UserTypeEnum.DEVELOPER
                || SecurityUtils.getUserContent().getType() == UserTypeEnum.ROOT;
        for (ConfigureExt configure : configures) {
            ConfigureValueDto configureValueDto = new ConfigureValueDto();
            configureValueDto.setId(configure.getId());
            configureValueDto.setCode(configure.getCode());
            configureValueDto.setName(configure.getName());
            configureValueDto.setRemark(configure.getRemark());
            configureValueDto.setScope(configure.getScope());
            configureValueDto.setDefaultValue(configure.getDefaultValue());
            configureValueDto.setGroupId(configure.getGroupId());
            configureValueDto.setGroupName(configure.getGroupName());
            configureValueDto.setCanEdit(configure.getScope() == ScopeEnum.Tenant || isDev);

            Optional<ConfigureValueExt> value = valueExts.stream().filter(s -> s.getId().equals(configure.getId())).findFirst();
            if (value.isPresent()) {
                configureValueDto.setValue(value.get().getValue());
                configureValueDto.setValueId(value.get().getValueId());
                configureValueDto.setCreateAt(value.get().getCreateAt());
                configureValueDto.setCreateTime(value.get().getCreateTime());
                configureValueDto.setLastModifiedAt(value.get().getLastModifiedAt());
                configureValueDto.setLastModifiedTime(value.get().getLastModifiedTime());
            }
            result.add(configureValueDto);
        }
        return WebUtils.success(result);
    }

    @GetMapping("getValueByCode/{code}")
    @ApiOperation(value = "getValueByCode", notes = "查询当前应用下的所有配置")
    public WebResult getValueByCode(@PathVariable("code") String code) {
        return WebUtils.success(service.getValueByCode(code));
    }

    @GetMapping("getValueById/{id}")
    @ApiOperation(value = "getValueById", notes = "根据")
    public WebResult getValueById(@PathVariable("id") String id) {
        return WebUtils.success(service.getValueById(id));
    }

    @PostMapping("delete/{id}")
    @ApiOperation(value = "delete", notes = "根据主键删除单个 Configure")
    public WebResult delete(@PathVariable("id") String id) {
        service.delete(id);
        return WebUtils.success();
    }

    @PostMapping("deleteValue/{id}")
    @ApiOperation(value = "deleteValue", notes = "根据主键删除单个 ConfigureValue")
    public WebResult deleteValue(@PathVariable("id") String id) {
        configureValueService.delete(id);
        return WebUtils.success();
    }


}